package vip.xiaonuo.sys.fymodule.thirdpa.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import vip.xiaonuo.sys.config.PayConfig;
import vip.xiaonuo.sys.config.TaskExecutePoolConfig;
import vip.xiaonuo.sys.core.util.PaPayUtil;
import vip.xiaonuo.sys.fymodule.account.entity.SxoSafetyUser;
import vip.xiaonuo.sys.fymodule.account.enums.CodeEnum;
import vip.xiaonuo.sys.fymodule.account.enums.SourceEnum;
import vip.xiaonuo.sys.fymodule.account.service.ISxoSafetyLogService;
import vip.xiaonuo.sys.fymodule.account.service.ISxoSafetyUserService;
import vip.xiaonuo.sys.fymodule.account.util.CommonUtil;
import vip.xiaonuo.sys.fymodule.account.util.HttpResult;
import vip.xiaonuo.sys.fymodule.account.util.TradetraceUtil;
import vip.xiaonuo.sys.fymodule.exception.BusinessException;
import vip.xiaonuo.sys.fymodule.order.entity.*;
import vip.xiaonuo.sys.fymodule.order.service.*;
import vip.xiaonuo.sys.fymodule.thirdpa.api.IBaseClient;
import vip.xiaonuo.sys.fymodule.thirdpa.api.impl.*;
import vip.xiaonuo.sys.fymodule.thirdpa.model.dto.*;
import vip.xiaonuo.sys.fymodule.thirdpa.model.vo.*;
import vip.xiaonuo.sys.fymodule.thirdpa.service.PaOrderService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class PaOrderServiceImpl extends BasePaServiceImpl implements PaOrderService {


    @Autowired
    private ISxoSafetyLogService sxoSafetyLogService;
    @Autowired
    private PayConfig payConfig;
    @Autowired
    private TaskExecutePoolConfig taskExecutePoolConfig;
    @Autowired
    private ISxoPaymentService sxoPaymentService;
    @Autowired
    private ISxoOrderService sxoOrderService;
    @Autowired
    private ISxoOrderDetailService sxoOrderDetailService;
    @Autowired
    private ISxoSafetyOrderService sxoSafetyOrderService;
    @Autowired
    private ISxoSafetyOrderDetailService sxoSafetyOrderDetailService;
    @Autowired
    private ISxoSafetyOrderRevokeService sxoSafetyOrderRevokeService;
    @Autowired
    private ISxoSafetyOrderRevokeDetailService sxoSafetyOrderRevokeDetailService;
    @Autowired
    private ISxoSafetySepAccService sxoSafetySepAccService;
    @Autowired
    private ISxoSafetySepAccDetailService sxoSafetySepAccDetailService;
    @Autowired
    private ISxoSafetySepAccRevokeDetailService sxoSafetySepAccRevokeDetailService;
    @Autowired
    private ISxoSafetyUserService sxoSafetyUserService;
    @Autowired
    private ISxoRefundLogService sxoRefundLogService;
    @Autowired
    private ISxoSafetyOrderSubsidyService sxoSafetyOrderSubsidyService;
    @Autowired
    private ISxoSafetyRegCreditService sxoSafetyRegCreditService;
    @Autowired
    private ISxoPayRequestLogService sxoPayRequestLogService;
    @Autowired
    private ISxoPayLogValueService sxoPayLogValueService;
    @Autowired
    private ISxoPayLogService sxoPayLogService;


    @Override
    public ThirdFreezeRechargeVo thirdFreezeRecharge(ThirdFreezeRechargeDto dto) {
        if (StrUtil.isEmpty(dto.getId())) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "id必须填写");
        }

        LambdaQueryWrapper<SxoSafetyOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SxoSafetyOrder::getOrderId, dto.getId());
        queryWrapper.in(SxoSafetyOrder::getOrdersStatus, "0", "2");
        queryWrapper.eq(SxoSafetyOrder::getStatus, "0");
        long count = sxoSafetyOrderService.count(queryWrapper);
        if (count > 0) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "当前订单已存在冻结充值；无法重复推送");
        }

        SxoOrder sxoOrder = sxoOrderService.getById(dto.getId());
        if (sxoOrder == null) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单ID错误");
        }
        if (!sxoOrder.getPayStatus().equals(1)) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "当前订单未支付或者已退款，无法进行冻结充值");
        }
        List<SxoOrderDetail> orderDetails = sxoOrderDetailService.listOrderDetailByOrderId(sxoOrder.getId());
        if (orderDetails.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "未找到订单明细");
        }
        long startTime = System.nanoTime();
        LambdaQueryWrapper<SxoPayLogValue> wqLv = new LambdaQueryWrapper<>();
        wqLv.eq(SxoPayLogValue::getBusinessId, sxoOrder.getId());
        List<SxoPayLogValue> sxoPayLogValues = sxoPayLogValueService.list(wqLv);
        if (sxoPayLogValues.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单logValue无数据");
        }
        SxoPayLogValue sxoPayLogValue = sxoPayLogValues.get(0);
        SxoPayLog payLog = sxoPayLogService.getById(sxoPayLogValue.getPayLogId());
        if (payLog == null) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单paylog无数据");
        }

        LambdaQueryWrapper<SxoPayRequestLog> wqRl = new LambdaQueryWrapper<>();
        wqRl.eq(SxoPayRequestLog::getTradeNo, payLog.getTradeNo());
        List<SxoPayRequestLog> payRequestLogs = sxoPayRequestLogService.list(wqRl);
        if (payRequestLogs.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单PayRequestLog无数据");
        }
        SxoPayRequestLog sxoPayRequestLog = payRequestLogs.get(0);
        String requestParams = sxoPayRequestLog.getRequestParams();
        if (StrUtil.isEmpty(sxoPayRequestLog.getRequestParams())) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单RequestParams无数据");
        }
        Map<String, String> map = buildOrderReq(requestParams);
        String totalOrderNo = map.get(PaPayUtil.CHANNEL_ORDER_NO);
        if (StrUtil.isEmpty(totalOrderNo)) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单ChannelOrderNo无数据");
        }
        long endTime = System.nanoTime();
        log.info("获取totalOrderNo:{};执行时间:{}秒", totalOrderNo, (endTime - startTime)  / 1_000_000_000.0);
        SxoSafetyUser safetyUser = sxoSafetyUserService.findUser(sxoOrder.getShopId(), SourceEnum.SHOP.getCode());
        if (safetyUser == null) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "当前商家未认证");
        }

        JSONObject json = new JSONObject();
        json.put("TxnCode", "KFEJZB6267");
        json.put("FundSummaryAcctNo", payConfig.getFundSummaryAcctNo());
        //订单信息
        String payOrderDate = CommonUtil.getYyyyMMdd(sxoOrder.getPayTime());
        if (payConfig.getTest() != null && payConfig.getTest()) {
            String st = String.valueOf(DateUtil.current() / 1000);
            payOrderDate = CommonUtil.getYyyyMMdd(st);
        }

        String tranTotalAmt = sxoOrder.getPayPrice().toString();
        String ordersCount = "1";
        String merNo = payConfig.getMerNo();
        String payChannelType = "0040";
        json.put("PayChannelType", payChannelType);
        json.put("PayChannelAssignMerNo", merNo);
        json.put("PayOrderDate", payOrderDate);
        json.put("TotalOrderNo", totalOrderNo);//第三方支付渠道产生的支付订单号
        json.put("TranTotalAmt", tranTotalAmt);
        json.put("OrdersCount", ordersCount);

        SxoSafetyOrder safetyOrder = new SxoSafetyOrder();
        String data = DateUtil.now();
        safetyOrder.setUserId(sxoOrder.getUserId());
        safetyOrder.setOrderId(sxoOrder.getId());
        safetyOrder.setOrderNo(sxoOrder.getOrderNo());
        safetyOrder.setShopId(sxoOrder.getShopId());
        safetyOrder.setShopName("");
        safetyOrder.setTranNetMemberCode(safetyUser.getTranNetMemberCode());
        safetyOrder.setPayChannelType(payChannelType);
        safetyOrder.setPayChannelAssignMerNo(merNo);
        safetyOrder.setPayOrderDate(payOrderDate);
        safetyOrder.setTotalOrderNo(totalOrderNo);
        safetyOrder.setTranTotalAmt(tranTotalAmt);
        safetyOrder.setOrdersCount(ordersCount);
        safetyOrder.setOrdersStatus(0);
        safetyOrder.setPushTime(data);
        safetyOrder.setStatus(0);
        safetyOrder.setAddTime(data);
        safetyOrder.setUpdTime(data);
        sxoSafetyOrderService.save(safetyOrder);
        //分账信息
        List<Map<String, Object>> tranItems = new ArrayList<>();
        List<SxoSafetyOrderDetail> details = new ArrayList<>();
        for (SxoOrderDetail sxoOrderDetail : orderDetails) {
            Map<String, Object> item = new HashMap<>();
            String subOrderFillCommission = "0";
            String subFillOrderNo = TradetraceUtil.buildTradetracePay();
            String subOrderFillRemark = "";
            String subOrderFillDesc = "";
            item.put("SubOrderFillSubAcctNo", safetyUser.getSubAcctNo());
            item.put("SubOrderFillAmt", sxoOrderDetail.getTotalPrice().toString());
            item.put("SubOrderFillCommission", subOrderFillCommission);
            item.put("SubFillOrderNo", subFillOrderNo);
            item.put("SubOrderFillDesc", subOrderFillDesc);//描述订单的用途
            item.put("SubOrderFillRemark", subOrderFillRemark);
            item.put("SubOrderFillReservedMsg", "");
            tranItems.add(item);

            SxoSafetyOrderDetail detail = new SxoSafetyOrderDetail();
            detail.setSafetyOrderId(safetyOrder.getId());
            detail.setGoodsId(sxoOrderDetail.getGoodsId());
            detail.setSubOrderFillSubAcctNo(safetyUser.getSubAcctNo());
            detail.setSubOrderFillAmt(sxoOrderDetail.getTotalPrice().toString());
            detail.setSubOrderFillCommission(subOrderFillCommission);
            detail.setSubFillOrderNo(subFillOrderNo);
            detail.setSubOrderFillDesc(subOrderFillDesc);
            detail.setSubOrderFillRemark(subOrderFillRemark);
            details.add(detail);
        }
        json.put("TranItemArray", tranItems);
        sxoSafetyOrderDetailService.saveBatch(details);


        SxoSafetyOrder mod = new SxoSafetyOrder();
        mod.setId(safetyOrder.getId());
        mod.setUpdTime(DateUtil.now());

        ThirdFreezeRechargeVo vo = new ThirdFreezeRechargeVo();
        try {
            IBaseClient baseClient = new ThirdFreezeRechargeApi(sxoSafetyLogService, taskExecutePoolConfig);
            HttpResult httpResult = baseClient.execute(json);
            JSONObject extenddata = handleError(httpResult);
            String jzbAcceptSeqNo = extenddata.getString("JzbAcceptSeqNo");
            mod.setJzbAcceptSeqNo(jzbAcceptSeqNo);
            mod.setCnsmrSeqNo(extenddata.getString(PaPayUtil.CNSMR_SEQ_NO));
            sxoSafetyOrderService.updateById(mod);
            vo.setJzbAcceptSeqNo(jzbAcceptSeqNo);
            return vo;
        } catch (Exception e) {
            mod.setOrdersStatus(-1);
            mod.setErrorMsg(e.getMessage());
            sxoSafetyOrderService.updateById(mod);
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), e.getMessage());
        }
    }

    @Override
    public ThirdFreezeRechargeCancelVo thirdFreezeRechargeCancel(ThirdFreezeRechargeCancelDto dto) {
        if (StrUtil.isEmpty(dto.getOrderId())) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单id必须填写");
        }
        LambdaQueryWrapper<SxoSafetyOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SxoSafetyOrder::getOrderId, dto.getOrderId());
        queryWrapper.in(SxoSafetyOrder::getOrdersStatus, "0", "2");
        queryWrapper.eq(SxoSafetyOrder::getStatus, "0");
        List<SxoSafetyOrder> safetyOrders = sxoSafetyOrderService.list(queryWrapper);
        if (safetyOrders == null) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单ID错误");
        }
        SxoSafetyOrder safetyOrder = safetyOrders.get(0);
        LambdaQueryWrapper<SxoSafetyOrderDetail> qw = new LambdaQueryWrapper<>();
        qw.eq(SxoSafetyOrderDetail::getSafetyOrderId, safetyOrder.getId());
        List<SxoSafetyOrderDetail> orderDetails = sxoSafetyOrderDetailService.list(qw);
        if (orderDetails.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "冻结充值明细错误");
        }

        LambdaQueryWrapper<SxoRefundLog> rq = new LambdaQueryWrapper<>();
        rq.eq(SxoRefundLog::getBusinessId, safetyOrder.getOrderId());
        rq.in(SxoRefundLog::getBusinessType, "order");
        rq.orderByDesc(SxoRefundLog::getId);
        List<SxoRefundLog> sxoRefundLogs = sxoRefundLogService.list(rq);
        if (sxoRefundLogs.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "未找到退款记录");
        }
        SxoRefundLog sxoRefundLog = sxoRefundLogs.get(0);

        JSONObject json = new JSONObject();
        json.put("TxnCode", "KFEJZB6268");
        json.put("FundSummaryAcctNo", payConfig.getFundSummaryAcctNo());
        //订单信息
        json.put("PayChannelType", safetyOrder.getPayChannelType());
        json.put("PayChannelAssignMerNo", safetyOrder.getPayChannelAssignMerNo());
        json.put("OldPayOrderDate", safetyOrder.getPayOrderDate());
        json.put("TotalOrderNo", safetyOrder.getTotalOrderNo());//第三方支付渠道产生的支付订单号
        json.put("TranTotalAmt", sxoRefundLog.getRefundPrice().toString());
        json.put("OrdersCount", safetyOrder.getOrdersCount());

        //分账信息
        List<Map<String, Object>> tranItems = new ArrayList<>();
        List<SxoSafetyOrderRevokeDetail> list = new ArrayList<>();
        for (SxoSafetyOrderDetail sxoOrderDetail : orderDetails) {
            Map<String, Object> item = new HashMap<>();
            String subOrderFillCommission = "0";


            String subOrderFillDesc = "退货";
            item.put("SubOrderRefundSubAcctNo", sxoOrderDetail.getSubOrderFillSubAcctNo());
            item.put("SubOrderRefundAmt", sxoRefundLog.getRefundPrice().toString());
            item.put("SubOrderRefundCommission", subOrderFillCommission);
            item.put("OldPaySubOrderNo", sxoOrderDetail.getSubFillOrderNo());
            item.put("SubOrderRefundRemark", subOrderFillDesc);//描述订单的用途
            item.put("SubOrderRefundReservedMsg", "");
            tranItems.add(item);

            SxoSafetyOrderRevokeDetail revokeDetail = new SxoSafetyOrderRevokeDetail();
            revokeDetail.setSafetyOrderId(sxoOrderDetail.getSafetyOrderId());
            revokeDetail.setUserId(safetyOrder.getUserId());
            revokeDetail.setOrderId(safetyOrder.getOrderId());
            revokeDetail.setOrderNo(safetyOrder.getOrderNo());
            revokeDetail.setShopId(safetyOrder.getShopId());
            revokeDetail.setGoodsId(sxoOrderDetail.getGoodsId());

            revokeDetail.setSubOrderRefundSubAcctNo(sxoOrderDetail.getSubOrderFillSubAcctNo());
            revokeDetail.setSubOrderRefundAmt(sxoRefundLog.getRefundPrice().toString());
            revokeDetail.setSubOrderRefundCommission(subOrderFillCommission);
            revokeDetail.setOldPaySubOrderNo(sxoOrderDetail.getSubFillOrderNo());
            revokeDetail.setSubOrderRefundRemark(subOrderFillDesc);
            revokeDetail.setStatus(0);
            revokeDetail.setAddTime(DateUtil.now());
            revokeDetail.setUpdTime(DateUtil.now());
            list.add(revokeDetail);
        }
        sxoSafetyOrderRevokeDetailService.saveBatch(list);
        json.put("TranItemArray", tranItems);

        ThirdFreezeRechargeCancelVo vo = new ThirdFreezeRechargeCancelVo();


        List<SxoSafetyOrderRevokeDetail> mods = new ArrayList<>();

        try {
            IBaseClient baseClient = new ThirdFreezeRechargeCancelApi(sxoSafetyLogService, taskExecutePoolConfig);
            HttpResult httpResult = baseClient.execute(json);
            JSONObject extenddata = handleError(httpResult);
            String jzbAcceptSeqNo = extenddata.getString("JzbAcceptSeqNo");

            for (SxoSafetyOrderRevokeDetail detail : list) {
                SxoSafetyOrderRevokeDetail mod = new SxoSafetyOrderRevokeDetail();
                mod.setId(detail.getId());
                mod.setUpdTime(DateUtil.now());
                mod.setJzbAcceptSeqNo(jzbAcceptSeqNo);
                mod.setCnsmrSeqNo(extenddata.getString(PaPayUtil.CNSMR_SEQ_NO));
                mods.add(mod);
            }

            SxoSafetyOrder orderMod = new SxoSafetyOrder();
            orderMod.setId(safetyOrder.getId());
            orderMod.setRevokeStatus(1);
            orderMod.setRevokeTime(DateUtil.now());

            sxoSafetyOrderRevokeDetailService.updateBatchById(mods);
            sxoSafetyOrderService.updateById(orderMod);
            vo.setJzbAcceptSeqNo(jzbAcceptSeqNo);
            return vo;
        } catch (Exception e) {
            for (SxoSafetyOrderRevokeDetail detail : list) {
                SxoSafetyOrderRevokeDetail mod = new SxoSafetyOrderRevokeDetail();
                mod.setId(detail.getId());
                mod.setUpdTime(DateUtil.now());
                mod.setErrorMsg(e.getMessage());
                mods.add(mod);
            }
            sxoSafetyOrderRevokeDetailService.updateBatchById(mods);
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), e.getMessage());
        }

    }

    @Override
    public SubsidyQuestVo subsidyQuest(SubsidyQuestDto dto) {
        if (StrUtil.isEmpty(dto.getOrderId())) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单id必须填写");
        }
        LambdaQueryWrapper<SxoSafetyOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SxoSafetyOrder::getOrderId, dto.getOrderId());
        queryWrapper.eq(SxoSafetyOrder::getOrdersStatus, "0");
        queryWrapper.eq(SxoSafetyOrder::getStatus, "0");
        List<SxoSafetyOrder> safetyOrders = sxoSafetyOrderService.list(queryWrapper);
        if (safetyOrders.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单ID错误");
        }
        SxoSafetyOrder safetyOrder = safetyOrders.get(0);
        LambdaQueryWrapper<SxoSafetyOrderDetail> qw = new LambdaQueryWrapper<>();
        qw.eq(SxoSafetyOrderDetail::getSafetyOrderId, safetyOrder.getId());
        List<SxoSafetyOrderDetail> orderDetails = sxoSafetyOrderDetailService.list(qw);
        if (orderDetails.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "冻结充值明细错误");
        }
        String subsidyOrderNo = TradetraceUtil.buildTradetraceSubsidy();
        SxoSafetyOrderDetail orderDetail = orderDetails.get(0);
        JSONObject json = new JSONObject();
        json.put("TxnCode", "KFEJZB6269");
        json.put("FundSummaryAcctNo", payConfig.getFundSummaryAcctNo());
        //订单信息
        String oldPaySubOrderNo = orderDetail.getSubFillOrderNo();
        String oldPayOrderDate = safetyOrder.getPayOrderDate();
        json.put("OldPaySubOrderNo", oldPaySubOrderNo);
        json.put("OldPayOrderDate", oldPayOrderDate);
        json.put("SubsidyOrderNo", subsidyOrderNo);
        json.put("SubsidyOutSubAcctNo", payConfig.getSubAcctNo13());
        json.put("SubsidyInSubAcctNo", dto.getSubsidyInSubAcctNo());
        json.put("SubsidyAmt", dto.getSubsidyAmt());
        json.put("SubsidyOrderDesc", "补贴");
        json.put("SubsidyRemark", "");

        SxoSafetyOrderSubsidy subsidyOrderSubsidy = new SxoSafetyOrderSubsidy();
        subsidyOrderSubsidy.setUserId(safetyOrder.getUserId());
        subsidyOrderSubsidy.setSafetyOrderId(safetyOrder.getId());
        subsidyOrderSubsidy.setOrderId(safetyOrder.getOrderId());
        subsidyOrderSubsidy.setOrderNo(safetyOrder.getOrderNo());
        subsidyOrderSubsidy.setShopId(safetyOrder.getShopId());
        subsidyOrderSubsidy.setOldPaySubOrderNo(oldPaySubOrderNo);
        subsidyOrderSubsidy.setOldPayOrderDate(oldPayOrderDate);
        subsidyOrderSubsidy.setSubsidyOrderNo(subsidyOrderNo);
        subsidyOrderSubsidy.setSubsidyOutSubAcctNo(payConfig.getSubAcctNo13());
        subsidyOrderSubsidy.setSubsidyInSubAcctNo(dto.getSubsidyInSubAcctNo());
        subsidyOrderSubsidy.setSubsidyAmt(dto.getSubsidyAmt());
        subsidyOrderSubsidy.setSubsidyOrderDesc("补贴");
        subsidyOrderSubsidy.setStatus(0);
        subsidyOrderSubsidy.setAddTime(DateUtil.now());
        subsidyOrderSubsidy.setUpdTime(DateUtil.now());
        sxoSafetyOrderSubsidyService.save(subsidyOrderSubsidy);


        try {
            IBaseClient baseClient = new SubsidyQuestApi(sxoSafetyLogService, taskExecutePoolConfig);
            HttpResult httpResult = baseClient.execute(json);
            JSONObject extenddata = handleError(httpResult);
            String jzbAcceptSeqNo = extenddata.getString("JzbAcceptSeqNo");

            String date = DateUtil.now();
            SxoSafetyOrderSubsidy mod = new SxoSafetyOrderSubsidy();
            mod.setId(subsidyOrderSubsidy.getId());
            mod.setSubsidyStatus(1);
            mod.setSubsidyTime(date);
            mod.setJzbAcceptSeqNo(jzbAcceptSeqNo);
            mod.setCnsmrSeqNo(extenddata.getString(PaPayUtil.CNSMR_SEQ_NO));
            mod.setErrorMsg("");
            sxoSafetyOrderSubsidyService.updateById(mod);

            SxoSafetyOrder order = new SxoSafetyOrder();
            order.setId(safetyOrder.getId());
            order.setSubsidyStatus(1);
            order.setSubsidyTime(date);
            sxoSafetyOrderService.updateById(order);

            SubsidyQuestVo vo = new SubsidyQuestVo();
            vo.setJzbAcceptSeqNo(jzbAcceptSeqNo);
            return vo;
        } catch (Exception e) {
            SxoSafetyOrderSubsidy mod = new SxoSafetyOrderSubsidy();
            mod.setId(subsidyOrderSubsidy.getId());
            mod.setUpdTime(DateUtil.now());
            mod.setErrorMsg(e.getMessage());
            sxoSafetyOrderSubsidyService.updateById(mod);
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), e.getMessage());
        }

    }

    @Override
    public SubsidyQuestVo subsidyCancel(SubsidyQuestDto dto) {
        if (StrUtil.isEmpty(dto.getOrderId())) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单id必须填写");
        }
        LambdaQueryWrapper<SxoSafetyOrderSubsidy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SxoSafetyOrderSubsidy::getOrderId, dto.getOrderId());
        queryWrapper.eq(SxoSafetyOrderSubsidy::getSubsidyStatus, "1");
        queryWrapper.eq(SxoSafetyOrderSubsidy::getStatus, "0");
        List<SxoSafetyOrderSubsidy> safetyOrders = sxoSafetyOrderSubsidyService.list(queryWrapper);
        if (safetyOrders.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单ID错误");
        }
        SxoSafetyOrderSubsidy subsidy = safetyOrders.get(0);


        JSONObject json = new JSONObject();
        json.put("TxnCode", "KFEJZB6270");
        json.put("FundSummaryAcctNo", payConfig.getFundSummaryAcctNo());
        //订单信息
        json.put("OldPaySubOrderNo", subsidy.getOldPaySubOrderNo());
        json.put("OldPayOrderDate", subsidy.getOldPayOrderDate());
        json.put("OldSubsidyOrderNo", subsidy.getSubsidyOrderNo());
        json.put("OldSubsidyOutSubAcctNo", subsidy.getSubsidyOutSubAcctNo());
        json.put("OldSubsidyInSubAcctNo", subsidy.getSubsidyInSubAcctNo());
        json.put("SubsidyCancelAmt", subsidy.getSubsidyAmt());
        json.put("SubsidyCancelRemark", "补贴撤销");


        try {
            IBaseClient baseClient = new SubsidyCancelApi(sxoSafetyLogService, taskExecutePoolConfig);
            HttpResult httpResult = baseClient.execute(json);
            JSONObject extenddata = handleError(httpResult);
            String jzbAcceptSeqNo = extenddata.getString("JzbAcceptSeqNo");

            String date = DateUtil.now();
            SxoSafetyOrderSubsidy mod = new SxoSafetyOrderSubsidy();
            mod.setId(subsidy.getId());
            mod.setSubsidyStatus(2);
            mod.setSubsidyTime(date);
            mod.setUpdTime(date);
            mod.setJzbAcceptRevNo(jzbAcceptSeqNo);
            mod.setRevCnsmrSeqNo(extenddata.getString(PaPayUtil.CNSMR_SEQ_NO));
            mod.setErrorMsg("");
            sxoSafetyOrderSubsidyService.updateById(mod);

            SxoSafetyOrder order = new SxoSafetyOrder();
            order.setId(subsidy.getSafetyOrderId());
            order.setSubsidyStatus(2);
            order.setSubsidyTime(date);
            sxoSafetyOrderService.updateById(order);

            SubsidyQuestVo vo = new SubsidyQuestVo();
            vo.setJzbAcceptSeqNo(jzbAcceptSeqNo);
            return vo;
        } catch (Exception e) {
            SxoSafetyOrderSubsidy mod = new SxoSafetyOrderSubsidy();
            mod.setId(subsidy.getId());
            mod.setUpdTime(DateUtil.now());
            mod.setErrorMsg("撤销:" + e.getMessage());
            sxoSafetyOrderSubsidyService.updateById(mod);
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), e.getMessage());
        }

    }

    @Override
    public SubAccountQuestVo subAccountQuest(SubAccountQuestDto dto) {
        if (StrUtil.isEmpty(dto.getOrderId())) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单id必须填写");
        }
        LambdaQueryWrapper<SxoSafetyOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SxoSafetyOrder::getOrderId, dto.getOrderId());
        queryWrapper.eq(SxoSafetyOrder::getOrdersStatus, "0");
        queryWrapper.eq(SxoSafetyOrder::getRevokeStatus, "0");
        queryWrapper.eq(SxoSafetyOrder::getSepStatus, "0");
        queryWrapper.eq(SxoSafetyOrder::getStatus, "0");
        List<SxoSafetyOrder> safetyOrders = sxoSafetyOrderService.list(queryWrapper);
        if (safetyOrders.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单ID错误");
        }
        SxoSafetyOrder safetyOrder = safetyOrders.get(0);
        LambdaQueryWrapper<SxoSafetyOrderDetail> qw = new LambdaQueryWrapper<>();
        qw.eq(SxoSafetyOrderDetail::getSafetyOrderId, safetyOrder.getId());
        List<SxoSafetyOrderDetail> orderDetails = sxoSafetyOrderDetailService.list(qw);
        if (orderDetails.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "冻结充值明细错误");
        }

        SxoSafetyOrderDetail orderDetail = orderDetails.get(0);
        JSONObject json = new JSONObject();
        json.put("TxnCode", "KFEJZB6271");
        json.put("FundSummaryAcctNo", payConfig.getFundSummaryAcctNo());
        //订单信息
        String outSubAcctNo = orderDetail.getSubOrderFillSubAcctNo();
        String oldPaySubOrderNo = orderDetail.getSubFillOrderNo();
        String oldPayOrderDate = safetyOrder.getPayOrderDate();
        json.put("OldPaySubOrderNo", oldPaySubOrderNo);
        json.put("OldPayOrderDate", oldPayOrderDate);
        json.put("OutSubAcctNo", outSubAcctNo);
        json.put("TranTotalAmt", safetyOrder.getTranTotalAmt());
        json.put("OrdersCount", "1");

        SxoSafetySepAcc sepAcc = new SxoSafetySepAcc();
        sepAcc.setUserId(safetyOrder.getUserId());
        sepAcc.setSafetyOrderId(safetyOrder.getId());
        sepAcc.setOrderId(safetyOrder.getOrderId());
        sepAcc.setOrderNo(safetyOrder.getOrderNo());
        sepAcc.setShopId(safetyOrder.getShopId());
        sepAcc.setOldPaySubOrderNo(oldPaySubOrderNo);
        sepAcc.setOldPayOrderDate(oldPayOrderDate);
        sepAcc.setOutSubAcctNo(outSubAcctNo);
        sepAcc.setTranTotalAmt(safetyOrder.getTranTotalAmt());
        sepAcc.setOrdersCount(safetyOrder.getOrdersCount());
        sepAcc.setSepStatus(1);
        sepAcc.setStatus(0);
        sepAcc.setAddTime(DateUtil.now());
        sepAcc.setUpdTime(DateUtil.now());

        List<Map<String, String>> list = new ArrayList<>();

        String subAcctOrderNo = TradetraceUtil.buildTradetraceAcc();
        String subAcctAmt = orderDetail.getAcctAmt();
        String subAcctOrderDesc = "分账";
        Map<String, String> item = new HashMap<>();
        item.put("SubAcctOrderNo", subAcctOrderNo);
        item.put("InSubAcctNo", outSubAcctNo);
        item.put("SubAcctAmt", subAcctAmt);
        item.put("SubAcctOrderDesc", subAcctOrderDesc);
        item.put("SubAcctRemark", "");
        list.add(item);

        String subAcctOrderNo1 = TradetraceUtil.buildTradetraceAccSer();
        String subAcctAmt1 = orderDetail.getSerAcctAmt();
        Map<String, String> item1 = new HashMap<>();
        item1.put("SubAcctOrderNo", subAcctOrderNo1);
        item1.put("InSubAcctNo", payConfig.getSubAcctNo3());
        item1.put("SubAcctAmt", subAcctAmt1);
        item1.put("SubAcctOrderDesc", subAcctOrderDesc);
        item1.put("SubAcctRemark", "");
        list.add(item1);

        json.put("TranItemArray", list);

        sxoSafetySepAccService.save(sepAcc);
        List<SxoSafetySepAccDetail> details = new ArrayList<>();
        for (Map<String, String> map : list) {
            SxoSafetySepAccDetail sepAccDetail = new SxoSafetySepAccDetail();
            sepAccDetail.setSepAccId(sepAcc.getId());
            sepAccDetail.setSubAcctOrderNo(map.get("SubAcctOrderNo"));
            sepAccDetail.setInSubAcctNo(map.get("InSubAcctNo"));
            sepAccDetail.setSubAcctAmt(map.get("SubAcctAmt"));
            sepAccDetail.setSubAcctOrderDesc(map.get("SubAcctOrderDesc"));
            sepAccDetail.setSubAcctRemark(map.get("SubAcctRemark"));

            details.add(sepAccDetail);
        }
        sxoSafetySepAccDetailService.saveBatch(details);


        try {
            IBaseClient baseClient = new SubAccountQuestApi(sxoSafetyLogService, taskExecutePoolConfig);
            HttpResult httpResult = baseClient.execute(json);
            JSONObject extenddata = handleError(httpResult);
            String jzbAcceptSeqNo = extenddata.getString("JzbAcceptSeqNo");

            String date = DateUtil.now();
            SxoSafetySepAcc mod = new SxoSafetySepAcc();
            mod.setId(sepAcc.getId());
            mod.setSepStatus(1);
            mod.setSepTime(date);
            mod.setCnsmrSeqNo(extenddata.getString(PaPayUtil.CNSMR_SEQ_NO));
            mod.setJzbAcceptSeqNo(jzbAcceptSeqNo);
            sxoSafetySepAccService.updateById(mod);

            SxoSafetyOrder order = new SxoSafetyOrder();
            order.setId(safetyOrder.getId());
            order.setSepStatus(1);
            order.setSepTime(date);
            sxoSafetyOrderService.updateById(order);

            SubAccountQuestVo vo = new SubAccountQuestVo();
            vo.setJzbAcceptSeqNo(jzbAcceptSeqNo);
            return vo;
        } catch (Exception e) {
            SxoSafetySepAcc mod = new SxoSafetySepAcc();
            mod.setId(sepAcc.getId());
            mod.setUpdTime(DateUtil.now());
            mod.setSepStatus(-1);
            mod.setErrorMsg(e.getMessage());
            sxoSafetySepAccService.updateById(mod);
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), e.getMessage());
        }
    }

    @Override
    public SubAccountQuestVo subAccountCancel(SubAccountQuestDto dto) {
        SxoSafetySepAcc sepAcc = sxoSafetySepAccService.getById(dto.getSepAccId());
        if (sepAcc == null) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "分账ID错误");
        }
        LambdaQueryWrapper<SxoSafetySepAccDetail> qw = new LambdaQueryWrapper<>();
        qw.eq(SxoSafetySepAccDetail::getSepAccId, sepAcc.getId());
        List<SxoSafetySepAccDetail> sepAccDetails = sxoSafetySepAccDetailService.list(qw);
        if (sepAccDetails.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "分账明细错误");
        }
        String jzbAcceptSeqNo = "";
        for (SxoSafetySepAccDetail detail : sepAccDetails) {
            jzbAcceptSeqNo = subAccountCancel(sepAcc, detail);
        }
        SubAccountQuestVo vo = new SubAccountQuestVo();
        vo.setJzbAcceptSeqNo(jzbAcceptSeqNo);
        return vo;
    }

    private String subAccountCancel(SxoSafetySepAcc sepAcc, SxoSafetySepAccDetail detail) {
        JSONObject json = new JSONObject();
        json.put("TxnCode", "KFEJZB6271");
        json.put("FundSummaryAcctNo", payConfig.getFundSummaryAcctNo());

        json.put("OldPaySubOrderNo", sepAcc.getOldPaySubOrderNo());
        json.put("OldPayOrderDate", sepAcc.getOldPayOrderDate());
        json.put("OldOutSubAcctNo", sepAcc.getOutSubAcctNo());
        json.put("TranTotalAmt", detail.getSubAcctAmt());
        json.put("OrdersCount", sepAcc.getOrdersCount());

        List<Map<String, String>> list = new ArrayList<>();
        Map<String, String> map = new HashMap<>();
        map.put("OldSubOrderNo", detail.getSubAcctOrderNo());
        map.put("OldInSubAcctNo", detail.getInSubAcctNo());
        map.put("SubAcctCancelAmt", detail.getSubAcctAmt());
        map.put("SubAcctCancelRemark", "分账撤销");
        list.add(map);

        json.put("TranItemArray", list);

        String date = DateUtil.now();
        try {
            IBaseClient baseClient = new SubAccountCancelApi(sxoSafetyLogService, taskExecutePoolConfig);
            HttpResult httpResult = baseClient.execute(json);
            JSONObject extenddata = handleError(httpResult);
            String jzbAcceptSeqNo = extenddata.getString("JzbAcceptSeqNo");

            SxoSafetySepAccDetail modDetail = new SxoSafetySepAccDetail();
            modDetail.setId(detail.getId());
            modDetail.setSepRevokeStatus(1);
            modDetail.setSepRevokeTime(date);
            modDetail.setCnsmrSeqNo(extenddata.getString(PaPayUtil.CNSMR_SEQ_NO));
            modDetail.setJzbAcceptSeqNo(jzbAcceptSeqNo);
            sxoSafetySepAccDetailService.updateById(modDetail);

            SxoSafetySepAcc mod = new SxoSafetySepAcc();
            mod.setId(sepAcc.getId());
            mod.setSepStatus(2);
            sxoSafetySepAccService.updateById(mod);

            SxoSafetyOrder order = new SxoSafetyOrder();
            order.setId(sepAcc.getId());
            order.setSepStatus(2);
            order.setSepTime(date);
            sxoSafetyOrderService.updateById(order);

            return jzbAcceptSeqNo;

        } catch (Exception e) {
            SxoSafetySepAccDetail mod = new SxoSafetySepAccDetail();
            mod.setId(detail.getId());
            mod.setSepRevokeStatus(-1);
            mod.setSepRevokeTime(date);
            mod.setErrorMsg(e.getMessage());
            sxoSafetySepAccDetailService.updateById(mod);
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), e.getMessage());
        }
    }

    @Override
    public RegisterBillSupportWithdrawVo registerBillSupportWithdraw(RegisterBillSupportWithdrawDto dto) {
        if (StrUtil.isEmpty(dto.getOrderId())) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单id必须填写");
        }
        if (StrUtil.isEmpty(dto.getSuspendAmt())) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "撤销金额必须填写");
        }
        LambdaQueryWrapper<SxoSafetyOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SxoSafetyOrder::getOrderId, dto.getOrderId());
        queryWrapper.eq(SxoSafetyOrder::getOrdersStatus, "0");
        queryWrapper.eq(SxoSafetyOrder::getRevokeStatus, "0");
        queryWrapper.eq(SxoSafetyOrder::getSepStatus, "0");
        queryWrapper.eq(SxoSafetyOrder::getStatus, "0");
        List<SxoSafetyOrder> safetyOrders = sxoSafetyOrderService.list(queryWrapper);
        if (safetyOrders.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "订单ID错误");
        }
        SxoSafetyOrder safetyOrder = safetyOrders.get(0);
        LambdaQueryWrapper<SxoSafetyOrderDetail> qw = new LambdaQueryWrapper<>();
        qw.eq(SxoSafetyOrderDetail::getSafetyOrderId, safetyOrder.getId());
        List<SxoSafetyOrderDetail> orderDetails = sxoSafetyOrderDetailService.list(qw);
        if (orderDetails.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "冻结充值明细错误");
        }

        SxoSafetyOrderDetail orderDetail = orderDetails.get(0);
        JSONObject json = new JSONObject();
        json.put("TxnCode", "KFEJZB6139");
        json.put("FundSummaryAcctNo", payConfig.getFundSummaryAcctNo());
        //订单信息
        String subAcctNo = orderDetail.getSubOrderFillSubAcctNo();
        String orderNo = TradetraceUtil.buildTradetraceAccReg();
        String tranFee = StrUtil.isEmpty(dto.getTranFee()) ? "0" : dto.getTranFee();
        String suspendAmt = dto.getSuspendAmt();
        json.put("SubAcctNo", subAcctNo);
        json.put("TranNetMemberCode", safetyOrder.getTranNetMemberCode());
        json.put("OrderNo", orderNo);
        json.put("SuspendAmt", suspendAmt);
        json.put("TranFee", tranFee);


        SxoSafetyRegCredit sepAcc = new SxoSafetyRegCredit();
        sepAcc.setUserId(safetyOrder.getUserId());
        sepAcc.setSafetyOrderId(safetyOrder.getId());
        sepAcc.setOrderId(safetyOrder.getOrderId());
        sepAcc.setOrderNo(safetyOrder.getOrderNo());
        sepAcc.setShopId(safetyOrder.getShopId());
        sepAcc.setSubAcctNo(subAcctNo);
        sepAcc.setTranNetMemberCode(safetyOrder.getTranNetMemberCode());
        sepAcc.setRegOrderNo(orderNo);
        sepAcc.setSuspendAmt(suspendAmt);
        sepAcc.setTranFee(tranFee);
        sepAcc.setRegStatus(1);
        sepAcc.setStatus(0);
        sepAcc.setAddTime(DateUtil.now());
        sepAcc.setUpdTime(DateUtil.now());

        sxoSafetyRegCreditService.save(sepAcc);

        try {
            IBaseClient baseClient = new RegisterBillSupportWithdrawApi(sxoSafetyLogService, taskExecutePoolConfig);
            HttpResult httpResult = baseClient.execute(json);
            JSONObject extenddata = handleError(httpResult);
            String jzbAcceptSeqNo = extenddata.getString("FrontSeqNo");

            String date = DateUtil.now();
            SxoSafetyRegCredit mod = new SxoSafetyRegCredit();
            mod.setId(sepAcc.getId());
            mod.setRegStatus(1);
            mod.setRegTime(date);
            mod.setCnsmrSeqNo(extenddata.getString(PaPayUtil.CNSMR_SEQ_NO));
            mod.setJzbAcceptSeqNo(jzbAcceptSeqNo);
            sxoSafetyRegCreditService.updateById(mod);

            RegisterBillSupportWithdrawVo vo = new RegisterBillSupportWithdrawVo();
            vo.setJzbAcceptSeqNo(jzbAcceptSeqNo);
            return vo;
        } catch (Exception e) {
            SxoSafetyRegCredit mod = new SxoSafetyRegCredit();
            mod.setId(sepAcc.getId());
            mod.setUpdTime(DateUtil.now());
            mod.setRegStatus(-1);
            mod.setErrorMsg(e.getMessage());
            sxoSafetyRegCreditService.updateById(mod);
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), e.getMessage());
        }
    }

    @Override
    public RegisterBillSupportWithdrawVo revRegisterBillSupportWithdraw(RegisterBillSupportWithdrawDto dto) {
        if (StrUtil.isEmpty(dto.getId())) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "id必须填写");
        }
        LambdaQueryWrapper<SxoSafetyRegCredit> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SxoSafetyRegCredit::getId, dto.getId());
        queryWrapper.eq(SxoSafetyRegCredit::getStatus, "0");
        queryWrapper.eq(SxoSafetyRegCredit::getRegStatus, "1");
        List<SxoSafetyRegCredit> credits = sxoSafetyRegCreditService.list(queryWrapper);
        if (credits.isEmpty()) {
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), "id错误或者已撤退挂账");
        }

        SxoSafetyRegCredit credit = credits.get(0);


        JSONObject json = new JSONObject();
        json.put("TxnCode", "KFEJZB6140");
        json.put("FundSummaryAcctNo", payConfig.getFundSummaryAcctNo());
        //订单信息
        json.put("SubAcctNo", credit.getSubAcctNo());
        json.put("TranNetMemberCode", credit.getTranNetMemberCode());
        json.put("OldOrderNo", credit.getRegOrderNo());
        json.put("CancelAmt", credit.getSuspendAmt());
        json.put("TranFee", credit.getTranFee());

        try {
            IBaseClient baseClient = new RevRegisterBillSupportWithdrawApi(sxoSafetyLogService, taskExecutePoolConfig);
            HttpResult httpResult = baseClient.execute(json);
            JSONObject extenddata = handleError(httpResult);
            String jzbAcceptSeqNo = extenddata.getString("FrontSeqNo");

            String date = DateUtil.now();
            SxoSafetyRegCredit mod = new SxoSafetyRegCredit();
            mod.setId(credit.getId());
            mod.setRegStatus(2);
            mod.setRegTime(date);
            mod.setRevCnsmrSeqNo(extenddata.getString(PaPayUtil.CNSMR_SEQ_NO));
            mod.setJzbAcceptRevNo(jzbAcceptSeqNo);
            sxoSafetyRegCreditService.updateById(mod);

            RegisterBillSupportWithdrawVo vo = new RegisterBillSupportWithdrawVo();
            vo.setJzbAcceptSeqNo(jzbAcceptSeqNo);
            return vo;
        } catch (Exception e) {
            SxoSafetyRegCredit mod = new SxoSafetyRegCredit();
            mod.setId(credit.getId());
            mod.setUpdTime(DateUtil.now());
            mod.setRegStatus(-2);
            mod.setErrorMsg("撤销失败：" + e.getMessage());
            sxoSafetyRegCreditService.updateById(mod);
            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), e.getMessage());
        }
    }

    @Override
    public TraFinalStatusQueryVo traFinalStatusQuery(TraFinalStatusQueryDto dto) {
        JSONObject json = new JSONObject();
        json.put("TxnCode", "KFEJZB6273");
        json.put("FundSummaryAcctNo", payConfig.getFundSummaryAcctNo());
        //订单信息
        json.put("OldJzbAcceptSeqNo", dto.getOldJzbAcceptSeqNo());

        try {
            IBaseClient baseClient = new TraFinalStatusQueryApi(sxoSafetyLogService, taskExecutePoolConfig);
            HttpResult httpResult = baseClient.execute(json);
            JSONObject extenddata = handleError(httpResult);

            JSONObject obj = buildResult(extenddata);
            return JSONObject.parseObject(obj.toJSONString(), TraFinalStatusQueryVo.class);
        } catch (Exception e) {

            throw new BusinessException(CodeEnum.SERVER_ERROR.getCode(), e.getMessage());
        }
    }

}
